package com.cqupt.scanning.system.file.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cqupt.scanning.handler.exception.MyException;
import com.cqupt.scanning.security.utils.ResponseUtil;
import com.cqupt.scanning.system.acl.entity.AclUser;
import com.cqupt.scanning.system.acl.service.AclUserService;
import com.cqupt.scanning.system.admin.entity.*;
import com.cqupt.scanning.system.admin.service.*;
import com.cqupt.scanning.system.file.entity.bo.ChildBo;
import com.cqupt.scanning.system.file.entity.bo.MesurementBO;
import com.cqupt.scanning.system.file.entity.bo.MesurementBearingBo;
import com.cqupt.scanning.system.file.helper.*;
import com.cqupt.scanning.system.file.helper.utils.MultipartFileToFileUtil;
import com.cqupt.scanning.system.file.helper.utils.TimeFormatUtil;
import com.cqupt.scanning.system.file.helper.utils.UnZipUtil;
import com.cqupt.scanning.system.file.service.FileService;
import com.cqupt.scanning.system.statistics.entity.CalculatedDataFoot;
import com.cqupt.scanning.system.statistics.entity.CalculatedDataThree;
import com.cqupt.scanning.system.statistics.service.CalculatedDataThreeService;
import com.cqupt.scanning.system.statistics.service.StatisticsService;
import com.cqupt.scanning.system.utils.result.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @Data: 2021/7/6 20:37
 * @Author: 宋宝梁
 */
@Service
@Slf4j
public class FileServiceImpl implements FileService {

    private FilePathConfig filePathConfig;
    private GenerateThreePDF generateThreePDF;
    private DepartmentService departmentService;
    private DeviceFootService deviceFootService;
    private DeviceThreeService deviceThreeService;
    private OrganizationService organizationService;
    private PatientFootService patientFootService;
    private PatientThreeService patientThreeService;
    private PatientThreeBearingService patientThreeBearingService;
    private CopLeftFootService copLeftFootService;
    private CopRightFootService copRightFootService;
    private FeatureDataService featureDataService;
    private MesurementService mesurementService;
    private MesurementBearingService mesurementBearingService;
    private AclUserService aclUserService;
    private LandmarkCoordinatesThreeService landmarkCoordinatesThreeService;
    private LandmarkCoordinatesThreeBearingService landmarkCoordinatesThreeBearingService;
    private StatisticsService calculatedDataFootService;
    private CalculatedDataThreeService calculatedDataThreeService;



    @Autowired
    private ObjectFactory<GenerateFootPDF> objFactory;


    @Autowired
    public FileServiceImpl(FilePathConfig filePathConfig,
                           GenerateThreePDF generateThreePDF, DeviceFootService deviceFootService,
                           DepartmentService departmentService,OrganizationService organizationService,
                           PatientFootService patientFootService, PatientThreeService patientThreeService,
                           PatientThreeBearingService patientThreeBearingService, DeviceThreeService deviceThreeService,
                           CopLeftFootService copLeftFootService, CopRightFootService copRightFootService,
                           FeatureDataService featureDataService, MesurementService mesurementService,
                           MesurementBearingService mesurementBearingService, AclUserService aclUserService,
                           LandmarkCoordinatesThreeService landmarkCoordinatesThreeService, LandmarkCoordinatesThreeBearingService landmarkCoordinatesThreeBearingService,
                           CalculatedDataThreeService calculatedDataThreeService, StatisticsService calculatedDataFootService) {
        this.filePathConfig = filePathConfig;
        this.generateThreePDF = generateThreePDF;
        this.departmentService = departmentService;
        this.deviceFootService = deviceFootService;
        this.deviceThreeService = deviceThreeService;
        this.organizationService = organizationService;
        this.patientFootService = patientFootService;
        this.patientThreeService = patientThreeService;
        this.patientThreeBearingService = patientThreeBearingService;
        this.copLeftFootService = copLeftFootService;
        this.copRightFootService = copRightFootService;
        this.featureDataService = featureDataService;
        this.mesurementService = mesurementService;
        this.mesurementBearingService = mesurementBearingService;
        this.aclUserService = aclUserService;
        this.landmarkCoordinatesThreeService = landmarkCoordinatesThreeService;
        this.landmarkCoordinatesThreeBearingService = landmarkCoordinatesThreeBearingService;
        this.calculatedDataThreeService = calculatedDataThreeService;
        this.calculatedDataFootService = calculatedDataFootService;

    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public void handleFootFile(MultipartFile file, HttpServletRequest request, HttpServletResponse response) {
        String footFileRootDir = null;
        List<Map> savePathMap = null;
        try {
            if(file == null || file.isEmpty()) {
                ResponseUtil.out(response, R.error().message("请上传文件"));
                return;
            }

            footFileRootDir = filePathConfig.getSaveFootFilePath() + File.separator + TimeFormatUtil.getStrTime(TimeFormatUtil.ONE);
            File currentFootDir = new File(footFileRootDir);
            if (!currentFootDir.exists()) currentFootDir.mkdirs();
            File saveZipFile = MultipartFileToFileUtil.transferToFile(file, footFileRootDir);
            String saveZipFilePath = saveZipFile.getAbsolutePath(); // 压缩文件的保存位置
            File[] zipFile = currentFootDir.listFiles();
            if (zipFile == null || zipFile.length == 0) {
                ResponseUtil.out(response, R.error().message("请上传文件"));
                return;
            }

            UnZipUtil.doZip(zipFile[0], footFileRootDir); // 解压
            File[] files = currentFootDir.listFiles(); // 得到解压后的所有文件(含压缩文件)
            if (files == null || files.length == 0) {
                ResponseUtil.out(response, R.error().message("压缩文件为空"));
                return;
            }

            PatientFoot patientFoot = null;
            CopLeftFoot copLeftFoot = null;
            CopRightFoot copRightFoot = null;
            FeatureData featureData = null;
            List<String[]> csvListLeft = new ArrayList<>();
            List<String[]> csvListRight = new ArrayList<>();
            String leftFootCsvPath = null, rightFootCsvPath = null;
            for (File oneFile : files) {
                String oneFileName = oneFile.getName();
                if (oneFileName.contains("userinfo") && oneFileName.contains("json")) {
                    // 软件bug，解决该json文件重复数据
                    patientFoot = ReadUploadedFile.analysisJsonFile(oneFile, patientFoot, PatientFoot.class);
                    continue;
                }
                if (oneFileName.contains("left") && oneFileName.contains("json")) {
                    copLeftFoot = ReadUploadedFile.analysisJsonFile(oneFile, copLeftFoot, CopLeftFoot.class);
                    continue;
                }
                if (oneFileName.contains("right") && oneFileName.contains("json")) {
                    copRightFoot = ReadUploadedFile.analysisJsonFile(oneFile, copRightFoot, CopRightFoot.class);
                    continue;
                }
                if (oneFileName.contains("featureData") && oneFileName.contains("json")) {
                    featureData = ReadUploadedFile.analysisJsonFile(oneFile, featureData, FeatureData.class);
                    continue;
                }
                if (oneFileName.contains("leftFoot") && oneFileName.contains("csv")) {
                        leftFootCsvPath = oneFile.getAbsolutePath();
                        ReadUploadedFile.analysisCsvFile(oneFile, csvListLeft);
                    continue;
                }
                if (oneFileName.contains("rightFoot") && oneFileName.contains("csv")) {
                    rightFootCsvPath = oneFile.getAbsolutePath();
                    ReadUploadedFile.analysisCsvFile(oneFile, csvListRight);
                }
            }

            if (ObjectUtil.hasNull(patientFoot, copLeftFoot, copRightFoot, featureData, csvListLeft, csvListRight)) {
                ResponseUtil.out(response, R.error().message("文件数据异常"));
                return;
            }

            GenerateImage generateImage = new GenerateImage(filePathConfig.getTempImageDir());
            Map<String, Object> pictureData = new HashMap<>();
            generateImage.generateAllPictures(featureData, copLeftFoot, copRightFoot, csvListLeft, csvListRight, pictureData);

            GenerateFootPDF generateFootPDF = objFactory.getObject();
            savePathMap = generateFootPDF.execute(patientFoot, featureData, filePathConfig.getGaitTemplate(), filePathConfig.getBalanceTemplate(),
                    filePathConfig.getOutFileFootRootDirectory(), pictureData);

            String username = SecurityContextHolder.getContext().getAuthentication().getName();
            AclUser user = aclUserService.getOne(new QueryWrapper<AclUser>().eq("username", username).select("id"));
            DeviceFoot deviceFoot = deviceFootService.getOne(new QueryWrapper<DeviceFoot>().eq("user_id", user.getId()).select("dev_num"));

            DeviceFoot deviceFoot1 = deviceFootService.getOne(new QueryWrapper<DeviceFoot>().eq("user_id", user.getId()).select("dep_id"));

            Department department = departmentService.getOne(new QueryWrapper<Department>().eq("id",deviceFoot1.getDepId()).select("org_num"));
            Organization organization = organizationService.getOne(new QueryWrapper<Organization>().eq("org_num",department.getOrgNum()).select("org_name"));

            CalculatedDataFoot calculatedDataFoot = new CalculatedDataFoot();

            patientFoot.setZipFilePath(saveZipFilePath)
                    .setLeftFootCsvPath(leftFootCsvPath)
                    .setRightFootCsvPath(rightFootCsvPath)
                    .setFileGaitPath((String) savePathMap.get(1).get("gaitPath"))
                    .setFileBalancePath((String) savePathMap.get(1).get("balancePath"))
                    .setDevNum(deviceFoot.getDevNum())
                    .setOrgName(organization.getOrgName());

            patientFootService.save(patientFoot);

            BeanUtil.copyProperties(patientFoot, calculatedDataFoot,"id");
            calculatedDataFoot.setPatientFootId(patientFoot.getId());
            BeanUtil.copyProperties(featureData, calculatedDataFoot,"patientFootId");
            BeanUtil.copyProperties(savePathMap.get(0), calculatedDataFoot, "id","name","sex","birthDate","heigth","weigth","phone");
            calculatedDataFootService.save(calculatedDataFoot);

            copLeftFoot.setPatientFootId(patientFoot.getId());
            copRightFoot.setPatientFootId(patientFoot.getId());
            featureData.setPatientFootId(patientFoot.getId());
            copLeftFootService.save(copLeftFoot);
            copRightFootService.save(copRightFoot);
            featureDataService.save(featureData);

            ResponseUtil.out(response, R.ok().data("id", patientFoot.getId()));
            log.info("足底扫描文件[{{}}]上传成功,生成报告[{}]、[{}]", file.getOriginalFilename(), generateFootPDF.getGaitPDFName(), generateFootPDF.getBlancePDFName());
        } catch (Exception e) {
            // 异常时删除生成的文件
            File footFile = new File(System.getProperty("user.dir") + File.separator + footFileRootDir);
            if (savePathMap != null) {
                if (savePathMap.get(1).containsKey("outFilePath") && savePathMap.get(1).get("outFilePath")!=null) {
                    File saveFile = new File(System.getProperty("user.dir") + File.separator + savePathMap.get(1).get("outFilePath"));
                    if (saveFile.exists()) FileHandler.deleteDir(saveFile);
                }
            }
            if (footFile.exists()) FileHandler.deleteDir(footFile);
            e.printStackTrace();
            throw new MyException(20001, "上传失败");
        } finally {
            // 删除创建的临时图片
            File imagesFile = new File(System.getProperty("user.dir") + File.separator + filePathConfig.getTempImageDir());
            if (imagesFile.exists()) {
                FileHandler.deleteDir(imagesFile);
            }
        }
    }

    @Override
    public void downloadGaitPdf(Integer id, HttpServletResponse response) {
        PatientFoot patientFoot = patientFootService.getOne(new QueryWrapper<PatientFoot>().eq("id", id).select("file_gait_path"));
        String filePath = patientFoot.getFileGaitPath();
        DownloadFileHelper.downloadOneFile(filePath, "足底步态分析报告[{{}}]下载成功", response);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public void handleThreeFile(MultipartFile file, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String threeFileRootDir = null;
        String savePath = null;
        String uploadFileName = file.getOriginalFilename();
        List<String[]> lists = new ArrayList<>();
        try {
            if (file == null || file.isEmpty()) {
                ResponseUtil.out(response, R.error().message("请上传文件"));
                return;
            }
            threeFileRootDir = filePathConfig.getSaveThreeFilePath() + File.separator + TimeFormatUtil.getStrTime(TimeFormatUtil.ONE);

            File currentThreeDir = new File(threeFileRootDir);
            if (!currentThreeDir.exists()) currentThreeDir.mkdirs();     //创建文件夹
            File saveZipFile = MultipartFileToFileUtil.transferToFile(file, threeFileRootDir);   //transferTo方法:将收到的文件传输到给定的目标文件 跟路径没有关系
            String saveZipFilePath = saveZipFile.getAbsolutePath();
            File[] zipFile = currentThreeDir.listFiles();  //遍历文件夹中所有文件，包括子文件夹中的文件时，必须用listFiles（）方法
            if (zipFile == null || zipFile.length == 0) {
                ResponseUtil.out(response, R.error().message("请上传文件"));
                return;
            }

            UnZipUtil.doZip(zipFile[0], threeFileRootDir);  //解压
            File[] files = currentThreeDir.listFiles(); // 得到解压后的所有文件(含压缩文件)
            if (files == null || files.length < 1) {
                ResponseUtil.out(response, R.error().message("压缩文件为空"));
                return;
            }


            StringBuilder picturesPath = new StringBuilder();
            StringBuilder picturesPathBearing = new StringBuilder();
            MesurementBearingBo mesurementBearingBo = new MesurementBearingBo();
            MesurementBO mesurementBO = new MesurementBO();
            List<String> uslPathList = new ArrayList<>();
            CalculatedDataThree calculatedDataThree = new CalculatedDataThree();
            CalculatedDataThree calculatedDataThreeBearing = new CalculatedDataThree();

            for (File file1 : files) {   //遍历压缩包下的所有一级文件（含压缩包）  2个

                if (file1.isDirectory()) {    //判断一级文件是否为文件夹
                    File[] manyFiles1 = new File(threeFileRootDir, file1.getName()).listFiles();  //列出一级文件下的二级文件  4个（两个文件夹+两个usl）
                    if (manyFiles1 == null || manyFiles1.length < 1) {
                        ResponseUtil.out(response, R.error().message("压缩文件为空"));
                        return;
                    }
                    for (File oneFile : manyFiles1) {  //遍历二级文件，4个

                        if (oneFile.isDirectory()) {
                            File[] manyFiles = new File(file1, oneFile.getName()).listFiles();  //列出二级文件夹下的所有三级文件内容  8个
                            if (manyFiles == null || manyFiles.length < 1) {
                                ResponseUtil.out(response, R.error().message("压缩文件为空"));
                                return;
                            }
                            for (File child : manyFiles) {  //遍历所有三级文件内容，即csv和jpg等8个
                                String childName = child.getName();
                                System.out.println("childName:"+childName);
                                if (childName.contains("usl")) {
                                    uslPathList.add(childName);
                                }

                                if (childName.contains("Mesurement") && childName.contains("csv")) {
                                    ChildBo childBo = ReadUploadedFile.analysisCsvFile(child.toString());

                                    if (childBo.getWeightBearing().equals("0")) {
                                        BeanUtils.copyProperties(childBo, mesurementBO);
                                        BeanUtil.copyProperties(childBo,calculatedDataThree);
                                    } else if (childBo.getWeightBearing().equals("100")){
                                        BeanUtils.copyProperties(childBo, mesurementBearingBo);
                                        BeanUtil.copyProperties(childBo,calculatedDataThreeBearing);
                                    } else {
                                        ResponseUtil.out(response, R.error().message("压缩文件为空"));
                                        return;
                                    }
                                }
//                                if (childName.contains("jpg") || childName.contains("png") ) {
//                                    picturesPath.append(file1);
//                                    picturesPath.append(File.separator);
//                                    picturesPath.append(oneFile.getName());
//                                    picturesPath.append(File.separator);
//                                    picturesPath.append(childName);
//                                }
                            }
                        }
                    }
                    if (uslPathList.size() !=2) {
                        ResponseUtil.out(response, R.error().message("usl文件不存在"));
                        return;
                    }
                }
            }

                //非负重
            String baseInfo = mesurementBO.getBaseInfo();
            PatientThree patientThree = getPatientThree(baseInfo);

            String baseInfoBearing = mesurementBearingBo.getBaseInfo();
            PatientThreeBearing patientThreeBearing = getPatientThreeBearing(baseInfoBearing);
                String username = SecurityContextHolder.getContext().getAuthentication().getName();
                AclUser user = aclUserService.getOne(new QueryWrapper<AclUser>().eq("username", username).select("id"));
                DeviceThree deviceThree = deviceThreeService.getOne(new QueryWrapper<DeviceThree>().eq("user_id", user.getId()).select("dev_num"));
                BeanUtils.copyProperties(mesurementBO, patientThree);
                patientThree.setDevNum(deviceThree.getDevNum());

                patientThree.setZipFilePath(saveZipFilePath);

                savePath = generateThreePDF.execute(patientThree, mesurementBO, patientThreeBearing, mesurementBearingBo, filePathConfig.getTemplatePDF3(), filePathConfig.getOutFileThreeRootDirectory());
                patientThree.setFilePath(savePath);
                patientThreeService.save(patientThree);

            //三维excel表
            BeanUtils.copyProperties(patientThree, calculatedDataThree,"weightBearing","id");
            calculatedDataThree.setPatientThreeId(patientThree.getId());
            String bmi = "0";
            if (StrUtil.isEmpty(calculatedDataThree.getHeight()) || StrUtil.isEmpty(calculatedDataThree.getWeight()) || calculatedDataThree.getHeight().equals("0") || calculatedDataThree.getWeight().equals("0")) {
                bmi = "0";
            } else {
                bmi = String.valueOf(NumberUtil.round((Double.parseDouble(calculatedDataThree.getWeight()))/Math.pow(((Double.parseDouble(calculatedDataThree.getHeight()))/100),2),3));
            }
            calculatedDataThree.setBmi(bmi);
            calculatedDataThreeService.save(calculatedDataThree);



                LandmarkCoordinatesThree landmarkCoordinatesThree = new LandmarkCoordinatesThree();
                BeanUtils.copyProperties(mesurementBO, landmarkCoordinatesThree);
                landmarkCoordinatesThree.setPatientThreeId(patientThree.getId());
                landmarkCoordinatesThreeService.save(landmarkCoordinatesThree);

                Mesurement mesurement = new Mesurement();
                BeanUtils.copyProperties(mesurementBO, mesurement);
                mesurement.setPatientThreeId(patientThree.getId());
                mesurementService.save(mesurement);
                ResponseUtil.out(response, R.ok().data("id", patientThree.getId()));

                //负重
            String usernameBearing = SecurityContextHolder.getContext().getAuthentication().getName();
            AclUser userBearing = aclUserService.getOne(new QueryWrapper<AclUser>().eq("username", usernameBearing).select("id"));
            DeviceThree deviceThreeBearing = deviceThreeService.getOne(new QueryWrapper<DeviceThree>().eq("user_id", userBearing.getId()).select("dev_num"));

            BeanUtils.copyProperties(mesurementBearingBo, patientThreeBearing);
            patientThreeBearing.setDevNum(deviceThree.getDevNum());
            patientThreeBearing.setFilePath(savePath);   //和非负重路径一样
            patientThreeBearing.setZipFilePath(saveZipFilePath);  //和非负重路径一样

            patientThreeBearingService.save(patientThreeBearing);

            //三维excel表负重
            BeanUtils.copyProperties(patientThreeBearing, calculatedDataThreeBearing,"weightBearing","id");
            calculatedDataThreeBearing.setPatientThreeId(patientThreeBearing.getId());
            calculatedDataThreeBearing.setBmi(bmi);
            calculatedDataThreeService.save(calculatedDataThreeBearing);

            LandmarkCoordinatesThreeBearing landmarkCoordinatesThreeBearing = new LandmarkCoordinatesThreeBearing();
            BeanUtils.copyProperties(mesurementBearingBo, landmarkCoordinatesThreeBearing);
            landmarkCoordinatesThreeBearing.setPatientThreeBearingId(patientThreeBearing.getId());
            landmarkCoordinatesThreeBearingService.save(landmarkCoordinatesThreeBearing);

            MesurementBearing mesurementBearing = new MesurementBearing();
            BeanUtils.copyProperties(mesurementBearingBo, mesurementBearing);
            mesurementBearing.setPatientThreeBearingId(patientThreeBearing.getId());
            mesurementBearingService.save(mesurementBearing);
            ResponseUtil.out(response, R.ok().data("id", patientThreeBearing.getId()));


            log.info("三维扫描文件[{{}}]上传成功,生成报告[{}]", file.getOriginalFilename(), generateThreePDF.getPdfName());
        } catch (Exception e) {
            File threeFile = new File(System.getProperty("user.dir") + File.separator + threeFileRootDir);
            File saveFile = new File(System.getProperty("user.dir") + File.separator + savePath);
            if (threeFile.exists()) FileHandler.deleteDir(threeFile);
            if (saveFile.exists()) FileHandler.deleteDir(saveFile);
            e.printStackTrace();
            throw e;
        }
    }


    /**
     * 解析三维扫描病人的基本信息
     * @param baseInfo
     * @return
     */
    //非负重
    private PatientThree getPatientThree(String baseInfo) {
        String reg = "[^\u4e00-\u9fa5]";
        String time = null, date = null, sex = null, devNum = null, name = null;
        String[] arr = baseInfo.split(" ");
        PatientThree patientThree = new PatientThree();
        for (int i=arr.length-1; i>=0; i--) {
            if (i == arr.length-1) {
                time = arr[arr.length-1];
                continue;
            }
            if (i == arr.length-2) {
                date = arr[arr.length-2];
                continue;
            }
            if (i == arr.length-3) {
                String str = arr[arr.length-3];
                String[] s = str.split("_");
                devNum = s[0];
                continue;
            }
            if (i == arr.length-4) {
                sex = arr[arr.length-4];
                if (sex.contains("Female")) {
                    sex = "女";
                } else {
                    sex = "男";
                }
                continue;
            }
            if (i == arr.length-5) {
                 name =baseInfo.replaceAll(reg, "");
                if(name.equals("")){
                    name = arr[arr.length-6] +" "+arr[arr.length-5];
                }
                break;
            }
        }
        String testTime = date + " " + time;
        patientThree.setName(name);
        patientThree.setSex(sex);
//        patientThree.setDevNum(devNum);
        patientThree.setTestTime(testTime);
        return patientThree;
    }

    //负重
    private PatientThreeBearing getPatientThreeBearing(String baseInfoBearing) {
        String reg = "[^\u4e00-\u9fa5]";
        String time = null, date = null, sex = null, devNum = null;
        String[] arr = baseInfoBearing.split(" ");
        PatientThreeBearing patientThreeBearing = new PatientThreeBearing();
        for (int i=arr.length-1; i>=0; i--) {
            if (i == arr.length-1) {
                time = arr[arr.length-1];
                continue;
            }
            if (i == arr.length-2) {
                date = arr[arr.length-2];
                continue;
            }
            if (i == arr.length-3) {
                String str = arr[arr.length-3];
                String[] s = str.split("_");
                devNum = s[0];
                continue;
            }
            if (i == arr.length-4) {
                sex = arr[arr.length-4];
                if (sex.contains("Female")) {
                    sex = "女";
                } else {
                    sex = "男";
                }
                break;
            }
        }
        String testTime = date + " " + time;
        String name = baseInfoBearing.replaceAll(reg, "");
        patientThreeBearing.setName(name);
        patientThreeBearing.setSex(sex);
//        patientThreeBearing.setDevNum(devNum);
        patientThreeBearing.setTestTime(testTime);
        return patientThreeBearing;
    }


    @Override
    public void downloadThreeFile(Integer id, HttpServletResponse response) {
        PatientThree patientThree = patientThreeService.getOne(new QueryWrapper<PatientThree>().eq("id", id).select("file_path"));
        String filePath = patientThree.getFilePath();
        DownloadFileHelper.downloadOneFile(filePath, "三维扫描报告[{}]下载成功", response);
    }

    @Override
    public void downloadFootZipFile(Integer id, HttpServletResponse response) {
        PatientFoot patientFoot = patientFootService.getOne(new QueryWrapper<PatientFoot>().eq("id", id).select("zip_file_path"));
        String zipFilePath = patientFoot.getZipFilePath();
        DownloadFileHelper.downloadOneFile(zipFilePath, "足底扫描压缩文件[{}]下载成功", response);
    }

    @Override
    public void downloadThreeZipFile(Integer id, HttpServletResponse response) {
        PatientThree patientThree = patientThreeService.getOne(new QueryWrapper<PatientThree>().eq("id", id).select("zip_file_path"));
        String zipFilePath = patientThree.getZipFilePath();
        DownloadFileHelper.downloadOneFile(zipFilePath, "三维扫描压缩文件[{}]下载成功", response);
    }

    @Override
    public void downloadLeftCsvFile(Integer id, HttpServletResponse response) {
        PatientFoot patientFoot = patientFootService.getOne(new QueryWrapper<PatientFoot>().eq("id", id).select("left_foot_csv_path"));
        String leftFootCsvPath = patientFoot.getLeftFootCsvPath();
        DownloadFileHelper.downloadOneFile(leftFootCsvPath, "足底扫描左脚csv文件[{}]下载成功", response);
    }

    @Override
    public void downloadRightCsvFile(Integer id, HttpServletResponse response) {
        PatientFoot patientFoot = patientFootService.getOne(new QueryWrapper<PatientFoot>().eq("id", id).select("right_foot_csv_path"));
        String rightFootCsvPath = patientFoot.getRightFootCsvPath();
        DownloadFileHelper.downloadOneFile(rightFootCsvPath, "足底扫描右脚csv文件[{}]下载成功", response);

    }

    @Override
    public void downloadBalancePdf(Integer id, HttpServletResponse response) {
        PatientFoot patientFoot = patientFootService.getOne(new QueryWrapper<PatientFoot>().eq("id", id).select("file_balance_path"));
        String zipFilePath = patientFoot.getFileBalancePath();
        DownloadFileHelper.downloadOneFile(zipFilePath, "足底平衡分析报告[{}]下载成功", response);
    }

    @Override
    public R downloadBatchFootZipFile(String name, String ageLower, String ageUpper, String doctor, String heightLower, String heightUpper, String measureMode, String sex, String weightLower, String weightUpper, String beginTime, String endTime, String phone, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        AclUser aclUser = aclUserService.getOne(new QueryWrapper<AclUser>().eq("username", username));
        Map<String, List<String>> map = new HashMap<>();
        if (aclUser.getType().equals("步态分析")) {
            DeviceFoot deviceFoot = deviceFootService.getOne(new QueryWrapper<DeviceFoot>().select("dev_num").eq("user_id", aclUser.getId()));
            String devNum = deviceFoot.getDevNum();
//            QueryWrapper<PatientFoot> patientFoot = new QueryWrapper<PatientFoot>().like("dev_num",devNum).ge("create_time", startTime).le("create_time", endTime);
            QueryWrapper<PatientFoot> w = new QueryWrapper<>();
            w.eq("dev_num",devNum);
            if (!StrUtil.isEmpty(name)){
                w.like("name",name);
            }
            if (!StrUtil.isEmpty(ageLower) && !StrUtil.isEmpty(ageUpper)){
                w.ge("age", ageLower).le("age", ageUpper);
            }
            if (!StrUtil.isEmpty(doctor)){
                w.like("doctor",doctor);
            }
            if (!StrUtil.isEmpty(heightLower) && !StrUtil.isEmpty(heightUpper)){
                w.ge("height",heightLower).le("height",heightUpper);
            }
            if (!StrUtil.isEmpty(measureMode)){
                w.like("gaitMeasureMode",measureMode);
            }
            if (!StrUtil.isEmpty(sex)){
                w.eq("sex", sex);
            }
            if (!StrUtil.isEmpty(weightLower) && !StrUtil.isEmpty(weightUpper)){
                w.ge("weight",weightLower).le("weight",weightUpper);
            }
            if (!StrUtil.isEmpty(beginTime) && !StrUtil.isEmpty(endTime)){
                w.ge("create_time",beginTime).le("create_time",endTime);
            }
            if(!StrUtil.isEmpty(phone)){
                w.eq("phone",phone);
            }

            List<String> FileGaitPath=(patientFootService.list(w)).stream().map(e -> e.getFileGaitPath()).collect(Collectors.toList());
            map.put(aclUser.getUsername(),FileGaitPath);
            byte[] zipfile = DownloadFileHelper.zipFile(map,"足底报告",response);
            DownloadFileHelper.downloadBatchFiles(zipfile,request,response);
        }
        return R.error();
    }

    @Override
    public R downloadBatchBalanceZipFile(String name, String ageLower, String ageUpper, String doctor, String heightLower, String heightUpper, String measureMode, String sex, String weightLower, String weightUpper, String beginTime, String endTime, String phone, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        AclUser aclUser = aclUserService.getOne(new QueryWrapper<AclUser>().eq("username", username));
        Map<String, List<String>> map = new HashMap<>();
        if (aclUser.getType().equals("步态分析")) {
            DeviceFoot deviceFoot = deviceFootService.getOne(new QueryWrapper<DeviceFoot>().select("dev_num").eq("user_id", aclUser.getId()));
            String devNum = deviceFoot.getDevNum();
//            QueryWrapper<PatientFoot> patientFoot = new QueryWrapper<PatientFoot>().like("dev_num",devNum).ge("create_time", startTime).le("create_time", endTime);
            QueryWrapper<PatientFoot> w = new QueryWrapper<>();
            w.eq("dev_num",devNum);
            if (!StrUtil.isEmpty(name)){
                w.like("name",name);
            }
            if (!StrUtil.isEmpty(ageLower) && !StrUtil.isEmpty(ageUpper)){
                w.ge("age", ageLower).le("age", ageUpper);
            }
            if (!StrUtil.isEmpty(doctor)){
                w.like("doctor",doctor);
            }
            if (!StrUtil.isEmpty(heightLower) && !StrUtil.isEmpty(heightUpper)){
                w.ge("height",heightLower).le("height",heightUpper);
            }
            if (!StrUtil.isEmpty(measureMode)){
                w.like("gaitMeasureMode",measureMode);
            }
            if (!StrUtil.isEmpty(sex)){
                w.eq("sex", sex);
            }
            if (!StrUtil.isEmpty(weightLower) && !StrUtil.isEmpty(weightUpper)){
                w.ge("weight",weightLower).le("weight",weightUpper);
            }
            if (!StrUtil.isEmpty(beginTime) && !StrUtil.isEmpty(endTime)){
                w.ge("create_time",beginTime).le("create_time",endTime);
            }
            if(!StrUtil.isEmpty(phone)){
                w.eq("phone",phone);
            }
            List<String> FileBalanceFilePath=(patientFootService.list(w)).stream().map(e -> e.getFileBalancePath()).collect(Collectors.toList());
            map.put(aclUser.getUsername(),FileBalanceFilePath);
            byte[] zipfile = DownloadFileHelper.zipFile(map,"平衡报告",response);
            DownloadFileHelper.downloadBatchFiles(zipfile,request,response);
    }
        return R.error();
    }

    @Override
    public R downloadBatchThreeZipFile(String name, String ageLower, String ageUpper, String heightLower, String heightUpper, String sex, String weightLower, String weightUpper, String beginTime, String endTime, String phone, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String username = SecurityContextHolder.getContext().getAuthentication().getName();
        AclUser aclUser = aclUserService.getOne(new QueryWrapper<AclUser>().eq("username", username));
        Map<String, List<String>> map = new HashMap<>();
        if (aclUser.getType().equals("三维扫描")) {
            DeviceThree deviceThree = deviceThreeService.getOne(new QueryWrapper<DeviceThree>().select("dev_num").eq("user_id", aclUser.getId()));
            String devNum = deviceThree.getDevNum();
//            QueryWrapper<PatientThree> patientThree = new QueryWrapper<PatientThree>().like("dev_num",devNum).ge("create_time", startTime).le("create_time", endTime);
            QueryWrapper<PatientThree> w = new QueryWrapper<>();
            w.eq("dev_num",devNum);
            if (!StrUtil.isEmpty(name)){
                w.like("name",name);
            }
            if (!StrUtil.isEmpty(ageLower) && !StrUtil.isEmpty(ageUpper)){
                w.ge("age", ageLower).le("age", ageUpper);
            }
            if (!StrUtil.isEmpty(heightLower) && !StrUtil.isEmpty(heightUpper)){
                w.ge("height",heightLower).le("height",heightUpper);
            }
            if (!StrUtil.isEmpty(sex)){
                w.eq("sex", sex);
            }
            if (!StrUtil.isEmpty(weightLower) && !StrUtil.isEmpty(weightUpper)){
                w.ge("weight",weightLower).le("weight",weightUpper);
            }
            if (!StrUtil.isEmpty(beginTime) && !StrUtil.isEmpty(endTime)){
                w.ge("create_time",beginTime).le("create_time",endTime);
            }
            if(!StrUtil.isEmpty(phone)){
                w.eq("phone",phone);
            }
            List<String> FileThreePath=(patientThreeService.list(w)).stream().map(e -> e.getFilePath()).collect(Collectors.toList());
            map.put(aclUser.getUsername(),FileThreePath);
            byte[] zipfile = DownloadFileHelper.zipFile(map,"三维扫描报告",response);
            DownloadFileHelper.downloadBatchFiles(zipfile,request,response);
        }
        return R.error();
    }

    @Override
    public R downloadBatchOriginalFootZipFile(String name, String ageLower, String ageUpper, String doctor, String heightLower, String heightUpper, String measureMode, String sex, String weightLower, String weightUpper, String beginTime, String endTime, String userName, String phone, String orgName, HttpServletRequest request, HttpServletResponse response) throws IOException {
        List<AclUser> aclUser = aclUserService.list(new QueryWrapper<AclUser>().eq("note", 0).like("type","步态分析"));
        List<String> user = aclUser.stream().map(AclUser::getUsername).collect(Collectors.toList());
        Map<String, List<String>> map = new HashMap<>();
        for (int i=0;i<aclUser.size();i++)
        {
            DeviceFoot deviceFoot = deviceFootService.getOne(new QueryWrapper<DeviceFoot>().select("dev_num").eq("user_id", aclUser.get(i).getId()));
            String devNum = deviceFoot.getDevNum();
//            QueryWrapper<PatientFoot> patientFoot = new QueryWrapper<PatientFoot>().like("dev_num",devNum).ge("create_time", beginTime).le("create_time", endTime);
            QueryWrapper<PatientFoot> w = new QueryWrapper<>();
            if (!StrUtil.isEmpty(name)){
                w.like("name",name);
            }
            if (!StrUtil.isEmpty(ageLower) && !StrUtil.isEmpty(ageUpper)){
                w.ge("age", ageLower).le("age", ageUpper);
            }
            if (!StrUtil.isEmpty(doctor)){
                w.like("doctor",doctor);
            }
            if (!StrUtil.isEmpty(heightLower) && !StrUtil.isEmpty(heightUpper)){
                w.ge("height",heightLower).le("height",heightUpper);
            }
            if (!StrUtil.isEmpty(measureMode)){
                w.like("gaitMeasureMode",measureMode);
            }
            if (!StrUtil.isEmpty(sex)){
                w.eq("sex", sex);
            }
            if (!StrUtil.isEmpty(weightLower) && !StrUtil.isEmpty(weightUpper)){
                w.ge("weight",weightLower).le("weight",weightUpper);
            }
            if (!StrUtil.isEmpty(orgName)){
                w.like("org_name",orgName);
            }
            if (!StrUtil.isEmpty(devNum)){
                w.like("dev_num",devNum);
            }
            if (!StrUtil.isEmpty(beginTime) && !StrUtil.isEmpty(endTime)){
                w.ge("create_time",beginTime).le("create_time",endTime);
            }
            if(!StrUtil.isEmpty(phone)){
                w.eq("phone",phone);
            }
//            if (!StrUtil.isEmpty(userName)){
//                AclUser user = aclUserService.getOne(new QueryWrapper<AclUser>().eq("note",0).eq("username", userName).select("id"));
//                if(user==null){
//                    return R.error().message("未查询到"+userName+"的相关数据");
//                }
//                DeviceFoot deviceFoot = deviceFootService.getOne(new QueryWrapper<DeviceFoot>().eq("user_id", user.getId()).select("dev_num"));
//                w.like("dev_num",deviceFoot.getDevNum());
//            }

            List<String> ZipFilePath=(patientFootService.list(w)).stream().map(e -> e.getZipFilePath()).collect(Collectors.toList());
            map.put(user.get(i),ZipFilePath);
        }
        byte[] zipfile=DownloadFileHelper.zipFile(map,"步态分析源文件压缩包",response);
        DownloadFileHelper.downloadBatchFiles(zipfile,request,response);
        return R.ok();
    }

    @Override
    public R downloadBatchOriginalThreeZipFile(String name,String ageLower,String ageUpper,String doctor,String heightLower,String heightUpper,String measureMode,String sex,String weightLower,String weightUpper,String beginTime,String endTime,String userName,String phone,String orgName,String businessName,String address,String cityProvince,String country,String fax,
                                               String weightBearingLower, String weightBearingUpper,String dressShoe,String athleticShoe,String casualShoe,String heels,String age, HttpServletRequest request, HttpServletResponse response) throws IOException {
        List<AclUser> aclUser = aclUserService.list(new QueryWrapper<AclUser>().eq("note", 0).like("type","三维扫描"));
        List<String> user = aclUser.stream().map(AclUser::getUsername).collect(Collectors.toList());
        Map<String, List<String>> map = new HashMap<>();
        try {
             for (int i=0;i<aclUser.size();i++) {
                DeviceThree deviceThree = deviceThreeService.getOne(new QueryWrapper<DeviceThree>().select("dev_num").eq("user_id", aclUser.get(i).getId()));
                String devNum = deviceThree.getDevNum();
//                QueryWrapper<PatientThree> patientThree = new QueryWrapper<PatientThree>().like("dev_num",devNum).ge("create_time", beginTime).le("create_time", endTime);
                 QueryWrapper<PatientThree> w = new QueryWrapper<>();
                 w.like("dev_num",devNum);
                 if (!StrUtil.isEmpty(name)){
                     w.like("name",name);
                 }
                 if (!StrUtil.isEmpty(age)){
                     w.like("age",age);
                 }
                 if (!StrUtil.isEmpty(ageLower) && !StrUtil.isEmpty(ageUpper)){
                     w.ge("age", ageLower).le("age", ageUpper);
                 }
                 if (!StrUtil.isEmpty(doctor)){
                     w.like("doctor",doctor);
                 }
                 if (!StrUtil.isEmpty(heightLower) && !StrUtil.isEmpty(heightUpper)){
                     w.ge("height",heightLower).le("height",heightUpper);
                 }
                 if (!StrUtil.isEmpty(measureMode)){
                     w.like("gaitMeasureMode",measureMode);
                 }
                 if (!StrUtil.isEmpty(sex)){
                     w.eq("sex", sex);
                 }
                 if (!StrUtil.isEmpty(weightLower) && !StrUtil.isEmpty(weightUpper)){
                     w.ge("weight",weightLower).le("weight",weightUpper);
                 }
                 if (!StrUtil.isEmpty(orgName)){
                     w.like("org_name",orgName);
                 }
//                 if (!StrUtil.isEmpty(devNum)){
//                     w.like("dev_num",devNum);
//                 }
                 if (!StrUtil.isEmpty(beginTime) && !StrUtil.isEmpty(endTime)){
                     w.ge("create_time",beginTime).le("create_time",endTime);
                 }
                 if(!StrUtil.isEmpty(phone)){
                     w.eq("phone",phone);
                 }
                 if(!StrUtil.isEmpty(businessName)){
                     w.like("business_name",businessName);
                 }
                 if(!StrUtil.isEmpty(address)){
                     w.like("address",address);
                 }
                 if(!StrUtil.isEmpty(cityProvince)){
                     w.like("city_province",cityProvince);
                 }
                 if(!StrUtil.isEmpty(country)){
                     w.like("country",country);
                 }
                 if(!StrUtil.isEmpty(fax)){
                     w.like("fax",fax);
                 }
                 if (!StrUtil.isEmpty(weightBearingLower) && !StrUtil.isEmpty(weightBearingUpper)){
                     w.ge("weight_bearing",weightBearingLower).le("weight_bearing",weightBearingUpper);
                 }
                 if(!StrUtil.isEmpty(dressShoe)){
                     w.like("dress_shoe",dressShoe);
                 }
                 if(!StrUtil.isEmpty(athleticShoe)){
                     w.like("athletic_shoe",athleticShoe);
                 }
                 if(!StrUtil.isEmpty(casualShoe)){
                     w.like("casual_shoe",casualShoe);
                 }
                 if(!StrUtil.isEmpty(heels)){
                     w.like("heels",heels);
                 }
//                 if (!StrUtil.isEmpty(userName)){
//                     AclUser user1 = aclUserService.getOne(new QueryWrapper<AclUser>().eq("note",0).eq("username", userName).select("id"));
//                     if(user1==null){
//                         return R.error().message("未查询到"+userName+"的相关数据");
//                     }
//                     DeviceThree deviceThree = deviceThreeService.getOne(new QueryWrapper<DeviceThree>().eq("user_id", user.getId()).select("dev_num"));
//                     w.like("dev_num",deviceThree.getDevNum());
//                 }

                List<String> ZipFilePath1=(patientThreeService.list(w)).stream().map(e -> e.getZipFilePath()).collect(Collectors.toList());
                List<File> ZipFilePath= new ArrayList<>();
                List<String> uslZipPathList = new ArrayList<>();
            for(String oneZipFilePath1:ZipFilePath1)
            {
                String upperPath= new File(oneZipFilePath1).getParent();  //回到oneZipFilePath1的上一级目录
                File[] filePath =new File(upperPath).listFiles();
                HashMap<String, Integer> hashMap = new HashMap<>();
                for (File file1 : filePath) {
                    if(file1.toString().contains("_uslFile.zip")){
                        hashMap.put(file1.toString(),0);
                        uslZipPathList.add(file1.toString());
                    }else if(file1.toString().contains(oneZipFilePath1)){
                        hashMap.put(file1.toString(),1);
                    }else{
                        hashMap.put(file1.toString(),2);
                    }
                }

                for (File file1 : filePath) {
                    if(!hashMap.containsValue(0)) {
                        if (file1.isDirectory()) {
                            File[] manyFiles1 = new File(file1.toString()).listFiles();  //测试文件夹
                            String[] temp=oneZipFilePath1.split("\\.");
                            String uslZipTempPath =  temp[0]+"_uslFile.zip";
                            if (manyFiles1 == null || manyFiles1.length < 1) {
                                ResponseUtil.out(response, R.error().message("压缩文件为空"));
                            }
                            for (File file : manyFiles1) {
                                if (file.isDirectory()) {
                                    File[] manyFiles2 = new File(file1, file.getName()).listFiles();  //同名两个文件夹
                                    if (manyFiles2 == null || manyFiles2.length < 1) {
                                        ResponseUtil.out(response, R.error().message("压缩文件为空"));
                                    }
                                        for (File child : manyFiles2) {  //遍历所有三级文件内容，即csv和jpg等8个
                                            String childName = child.getName();
                                            if (childName.contains("usl")) {

                                                ZipFilePath.add(child);
                                                if (ZipFilePath.size() == 2) {
                                                            FileOutputStream fos2 = new FileOutputStream(new File(uslZipTempPath));
                                                            DownloadFileHelper.toZip(ZipFilePath, fos2);
                                                    ZipFilePath.removeAll(ZipFilePath);
                                                    uslZipPathList.add(uslZipTempPath);
                                                }

                                            }
                                        }

                                }
                            }
                        }
                    }
                }


            }

            map.put(user.get(i),uslZipPathList);
        }
        byte[] zipfile=DownloadFileHelper.zipFile(map,"三维扫描源文件压缩包",response);

        DownloadFileHelper.downloadBatchFiles(zipfile,request,response);
        return R.error();
        } catch (Exception e) {
            e.printStackTrace();
            throw new MyException(20001, "压缩失败");
        }
    }


    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = {Exception.class})
    public void handleModFile(MultipartFile file, HttpServletRequest request, HttpServletResponse response) throws IOException {
        String threeFileRootDir = null;
        String uploadFileName = file.getOriginalFilename();
        String[] uploadFileNameList =  uploadFileName.split("_");
        try {
            if (file == null || file.isEmpty()) {
                ResponseUtil.out(response, R.error().message("请上传文件"));
                return;
            }
            threeFileRootDir = filePathConfig.getSaveModBusFilePath()+File.separator+uploadFileNameList[0];

            File currentThreeDir = new File(threeFileRootDir);
            if (!currentThreeDir.exists()) currentThreeDir.mkdirs();     //创建文件夹
            File saveZipFile = MultipartFileToFileUtil.transferToFile(file, threeFileRootDir);   //transferTo方法:将收到的文件传输到给定的目标文件 跟路径没有关系
            log.info("ModBus文件[{{}}]上传成功", uploadFileName);
            ResponseUtil.out(response, R.ok().code(20000).message("文件上传成功"));
        } catch (Exception e) {

            File saveFile = new File(System.getProperty("user.dir") + File.separator + uploadFileName);
            if (saveFile.exists()) FileHandler.deleteDir(saveFile);
            e.printStackTrace();
            throw e;
        }
    }

}
